import { _decorator, Component, Node } from 'cc';
import { Unit } from '../Unit';
import { Global, RelicType, SkillData, SkillType, TechnologyData, TechnologyType, UnitType } from '../../Util/Global';
import GameEventMgr, { GameEvent } from '../../Model/GameEventMgr';
import { EconomicCom } from './EconomicCom';
import { SpawnerCom } from './SpawnerCom';
import AssetsMgr from '../../Model/AssetsMgr';
import { UnitPlanetBase } from '../UnitPlanetBase';
import { EarthCannonCom } from './EarthCannonCom';
import { UnitPlanet } from '../UnitPlanet';
import { DestructableCom } from './DestructableCom';
const { ccclass, property, requireComponent } = _decorator;

@ccclass('LevelUpCom')
// @requireComponent(Unit)
export class LevelUpCom extends Component {
    private _level: number = 1;

    get level() {
        return this._level;
    }
    set level(value: number) {
        if (Global.config['levelCfg'][this._level]) {
            this._level = value;
            this.capacitance = Global.config['levelCfg'][this.level - 1].capacitance;
            this.acceleration = Global.config['levelCfg'][this.level - 1].acceleration;
            this.maxSpeed = Global.config['levelCfg'][this.level - 1].maxSpeed;
            this.updataUnitData();
        }
    }

    /**最大电容 */
    capacitance: number = 100;
    /**移动加速度 */
    acceleration: number = 1.2;
    /**移动加速度 */
    maxSpeed: number = 10;

    relics: Map<RelicType, number> = new Map;
    technologyProduct: Map<TechnologyType, number> = new Map;
    skillMap: Map<SkillType, { lv: number, readyTime: number, maxCount: number }> = new Map;

    spawner: SpawnerCom = null;

    private _unit: UnitPlanetBase = null
    start() {
        this._unit = this.getComponent(UnitPlanetBase);
        this._unit.levelUpCom = this;
        // GameEventMgr.Register(this, GameEvent.UnitLevelUp, this.onLevelUpEventHandler.bind(this));
        this.updataUnitData();
        //敌人
        if (!this._unit.playerCtrl) {
            const playerData = Global.gameManager.playerData;
            const earthCannonProb = playerData.difficulty / 3;
            const shieldProb = playerData.difficulty / 3;

            const upgradeTechnology = (probability: number, technologyType: TechnologyType) => {
                const ran = Math.random();
                if (ran < probability) {
                    const num = Math.floor(ran * TechnologyData.TechnologyMap.get(technologyType).levelMax);
                    for (let i = 0; i < num; i++) {
                        this.UpTechnology(technologyType);
                    }
                }
            };

            upgradeTechnology(earthCannonProb, TechnologyType.EarthCannon);
            upgradeTechnology(shieldProb, TechnologyType.Shield);
        }
    }

    protected update(dt: number): void {
        for (let [k, v] of this.skillMap) {
            let data = SkillData.SkillMap.get(k);
            if (v.readyTime < data.coolTime * v.maxCount) {
                v.readyTime += dt;
            }
        }
    }

    protected onDisable(): void {
        this.destroy();
    }

    protected onLevelUpEventHandler(unit: Unit) {
        if (unit == this._unit && Global.config['levelCfg'][this._level]) {
            this.level = this.level + 1;

            this.updataUnitData();
        }
    }

    protected updataUnitData() {
        let economic = this.getComponent(EconomicCom);
        if (economic) {
            economic.electric_power_max = this.capacitance;
        }
        if (this._unit) {
            this._unit.moveAcceleration = this.acceleration;
            this._unit.maxSpeed = this.maxSpeed;
        }
        else {
            return;
        }

        if (this.spawner) {
            for (let i = 0; i < this.level; i++) {
                let spawnerCfg = Global.config['levelCfg'][i].unit_unlocked;
                if (spawnerCfg && spawnerCfg.length > 0) {
                    spawnerCfg.forEach((v: string) => {
                        this.spawner.AddProduct(AssetsMgr.getUnitPrefab(UnitType[v]));
                    })
                }
            }
        }

        if (this._unit == Global.gameManager.playerUnit) {
            let playerData = Global.gameManager.playerData;
            let orgRelic = playerData.relics;
            if (orgRelic != this.relics && orgRelic.size > 0) {
                orgRelic.forEach((v, k) => {
                    while (v-- > 0) {
                        this.AddRelic(k, v);
                    }
                })
            }
            let technologyProduct = playerData.technologyProduct;
            if (technologyProduct != this.technologyProduct && technologyProduct.size > 0) {
                technologyProduct.forEach((v, k) => {
                    while (v-- > 0) {
                        this.UpTechnology(k);
                    }
                })
            }
            GameEventMgr.Dispatch(GameEvent.PlayerDataChange);
        }
    }

    /**添加遗物 */
    public AddRelic(type: number, count: number = 1) {
        let get = true;
        let isPlayer = this._unit.playerCtrl;
        switch (type) {
            case RelicType.DysonTrackPlanA:
                // if (this.relics.has(RelicType.DysonTrackPlanB)) {
                //     this.relics.delete(RelicType.DysonTrackPlanB);
                // }
                this.relics.set(RelicType.DysonTrackPlanA, 1);
                break;
            case RelicType.DysonTrackPlanB:
                // if (this.relics.has(RelicType.DysonTrackPlanA)) {
                //     this.relics.delete(RelicType.DysonTrackPlanA);
                // }
                this.relics.set(RelicType.DysonTrackPlanB, 1);
                break;
            case RelicType.LightParticleStrike:
                let num = this.relics.get(RelicType.LightParticleStrike) || 0;
                this.relics.set(RelicType.LightParticleStrike, ++num);

                let skill = this.skillMap.get(SkillType.LightParticleStrike) || { lv: 0, readyTime: 0, maxCount: 1 };
                skill.lv = ++skill.lv;
                skill.readyTime = skill.readyTime || 0;
                skill.maxCount = skill.maxCount || 1;
                this.skillMap.set(SkillType.LightParticleStrike, skill);

                //激光子弹
                this.spawner.AddProduct(AssetsMgr.getUnitPrefab(UnitType.Bullet, 'BulletLaser'));
                break;
            default: get = false; break;
        }
        if (get && isPlayer) {
            Global.gameManager.playerData.relics = this.relics;
            Global.gameManager.playerData.skills = this.skillMap;
            GameEventMgr.Dispatch(GameEvent.PlayerDataChange);
        }
    }

    /**升级科技 */
    public UpTechnology(type: number) {

        let lv = this.technologyProduct.get(type) || 0;
        let technologyData = TechnologyData.TechnologyMap.get(type);
        if (technologyData && lv < technologyData.levelMax) {

            this.technologyProduct.set(type, ++lv);
        }
        else {
            return 0;
        }
        switch (type) {
            case TechnologyType.PlanetWarning:
                break;
            case TechnologyType.EarthCannon:
                if (this._unit.unitType == UnitType.UnitPlanet) {
                    let earthCannon = this._unit.getComponent(EarthCannonCom) || this._unit.addComponent(EarthCannonCom);
                    earthCannon.planet = <UnitPlanet>this._unit;
                    earthCannon.enabled = true;
                    earthCannon.addCannon();
                }
                break;
            case TechnologyType.Shield:
                if (this._unit.unitType == UnitType.UnitPlanet) {
                    let destructable = this._unit.getComponent(DestructableCom) || this._unit.addComponent(DestructableCom);
                    destructable.maxShield = 100 * lv;
                    destructable.shield_cost_electric = 10 * lv;
                    destructable.shield_recover_max_speed = 10 * lv;
                    destructable.unitEconomicCom = this._unit.getComponent(EconomicCom);
                }
                break;
            default: break;
        }

        if (this._unit.playerCtrl) {
            Global.gameManager.playerData.technologyProduct = this.technologyProduct;
        }

        return lv;
    }
}


